import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Vector;

import javax.swing.AbstractListModel;
import javax.swing.ComboBoxModel;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;


public class roomManagementDialog extends JDialog{
	
	// GUI
	private backgroundPanel panel;
	private JLabel searchLabel;
	private JTextField searchTextField;
	private JButton searchButton;
	private JButton createButton;
	private JButton scheduleButton;
	private JButton cleanButton;
	private JButton finishCleanButton;
	private JButton mergeButton;
	private JLabel mergeLabel;
	private MyComboBoxModel m1ComboBoxModel;
	private JComboBox m1ComboBox;
	private JLabel andLabel;
	private MyComboBoxModel m2ComboBoxModel;
	private JComboBox m2ComboBox;
	private JButton changeButton;
	private JLabel fromLabel;
	private MyComboBoxModel ch1ComboBoxModel;
	private JComboBox ch1ComboBox;
	private JLabel toLabel;
	private MyComboBoxModel ch2ComboBoxModel;
	private JComboBox ch2ComboBox;
	private JButton cancelButton;
	private JLabel cancelRoomLabel;
	private MyComboBoxModel cComboBoxModel;
	private JComboBox cComboBox;
	private MyComboBoxModel c2ComboBoxModel;
	private JComboBox c2ComboBox;
	private JButton backButton;
	
	// event handlers
	private SearchRoomHandler searchRoomHandler;
	private CreateRoomHandler createRoomHandler;
	private CheckScheduleHandler checkScheduleHandler;
	private CleanHandler cleanHandler;
	private FinishCleanHandler finishCleanHandler;
	private MergeRoomHandler mergeRoomHandler;
	private Merge1Handler merge1Handler;
	private Merge2Handler merge2Handler;
	private ChangeRoomHandler changeRoomHandler;
	private Change1Handler change1Handler;
	private Change2Handler change2Handler;
	private CancelRoomHandler cancelRoomHandler;
	private Cancel1Handler cancel1Handler;
	private Cancel2Handler cancel2Handler;
	private CancelHandler cancelHandler;
	
	// data controls
	private roomManager rm;
	
	public roomManagementDialog(roomManager initRm){
		rm = initRm;
		layoutGUI();
	}
	
	public void layoutGUI(){
		this.setTitle("Room Management");
		this.setResizable(false);
		panel = new backgroundPanel("background5.jpg",0,0,600,300);
		panel.setBackground(Color.WHITE);
		searchLabel = new JLabel("Room Search: ");
		//searchLabel.setForeground(Color.WHITE);
		searchTextField = new JTextField("Enter Room Number");
		searchButton = new JButton("Search");
		createButton = new JButton("Create Room");
		scheduleButton = new JButton("Check Room Schedule");
		cleanButton = new JButton("Clean");
		finishCleanButton = new JButton("Finish Cleaning");
		
		mergeButton = new JButton("Merge Room");
		mergeButton.setEnabled(false);
		mergeLabel = new JLabel("Merge: ");
		//mergeLabel.setForeground(Color.WHITE);
		m1ComboBoxModel = new MyComboBoxModel();
		m1ComboBoxModel.setList(rm.findRoomState(1));
		m1ComboBox = new JComboBox(m1ComboBoxModel);
		andLabel = new JLabel("and ");
		//andLabel.setForeground(Color.WHITE);
		m2ComboBoxModel = new MyComboBoxModel();
		m2ComboBox = new JComboBox(m2ComboBoxModel);
		m2ComboBox.setEnabled(false);
		
		changeButton = new JButton("Change Room");
		changeButton.setEnabled(false);
		fromLabel = new JLabel("From ");
		//fromLabel.setForeground(Color.WHITE);
		ch1ComboBoxModel = new MyComboBoxModel();
		ch1ComboBoxModel.setList(rm.findRoomState(1));
		ch1ComboBox = new JComboBox(ch1ComboBoxModel);
		toLabel = new JLabel("to ");
		//toLabel.setForeground(Color.WHITE);
		ch2ComboBoxModel = new MyComboBoxModel();
		ch2ComboBox = new JComboBox(ch2ComboBoxModel);
		ch2ComboBox.setEnabled(false);
		
		cancelButton = new JButton("Cancel Room");
		cancelButton.setEnabled(false);
		cancelRoomLabel = new JLabel("Room: ");
		//cancelRoomLabel.setForeground(Color.WHITE);
		cComboBoxModel = new MyComboBoxModel();
		cComboBoxModel.setList(rm.reservationRooms());
		cComboBox = new JComboBox(cComboBoxModel);
		c2ComboBoxModel = new MyComboBoxModel();
		c2ComboBox = new JComboBox(c2ComboBoxModel);
		c2ComboBox.setEnabled(false);
		
		backButton = new JButton("Back");
		
		// add handlers
		searchRoomHandler = new SearchRoomHandler();
		createRoomHandler = new CreateRoomHandler();
		checkScheduleHandler = new CheckScheduleHandler();
		cleanHandler = new CleanHandler();
		finishCleanHandler = new FinishCleanHandler();
		mergeRoomHandler = new MergeRoomHandler();
		merge1Handler = new Merge1Handler();
		merge2Handler = new Merge2Handler();
		changeRoomHandler = new ChangeRoomHandler();
		change1Handler = new Change1Handler();
		change2Handler = new Change2Handler();
		cancelRoomHandler = new CancelRoomHandler();
		cancel1Handler = new Cancel1Handler();
		cancel2Handler = new Cancel2Handler();
		cancelHandler = new CancelHandler();
		
		searchButton.addActionListener(searchRoomHandler);
		createButton.addActionListener(createRoomHandler);
		scheduleButton.addActionListener(checkScheduleHandler);
		cleanButton.addActionListener(cleanHandler);
		finishCleanButton.addActionListener(finishCleanHandler);
		mergeButton.addActionListener(mergeRoomHandler);
		m1ComboBox.addActionListener(merge1Handler);
		m2ComboBox.addActionListener(merge2Handler);
		changeButton.addActionListener(changeRoomHandler);
		ch1ComboBox.addActionListener(change1Handler);
		ch2ComboBox.addActionListener(change2Handler);
		cancelButton.addActionListener(cancelRoomHandler);
		cComboBox.addActionListener(cancel1Handler);
		c2ComboBox.addActionListener(cancel2Handler);
		backButton.addActionListener(cancelHandler);
		
		GridBagLayout layout = new GridBagLayout();
		panel.setLayout(layout);
		addComponent(searchLabel,			panel,	0,	0,	1,	1);
		addComponent(searchTextField,		panel,	1,	0,	1,	1);
		addComponent(searchButton,			panel,	2,	0,	1,	1);
		addComponent(createButton,			panel,	0,	1,	1,	1);
		addComponent(scheduleButton,		panel,	1,	1,	1,	1);
		addComponent(cleanButton,			panel,	2,	1,	1,	1);
		addComponent(finishCleanButton,		panel,	3,	1,	1,	1);
		addComponent(mergeButton,			panel,	0,	2,	1,	1);
		addComponent(mergeLabel,			panel,	1,	2,	1,	1);
		addComponent(m1ComboBox,			panel,	2,	2,	1,	1);
		addComponent(andLabel,				panel,	3,	2,	1,	1);
		addComponent(m2ComboBox,			panel,	4,	2,	1,	1);
		addComponent(changeButton,			panel,	0,	3,	1,	1);
		addComponent(fromLabel,				panel,	1,	3,	1,	1);
		addComponent(ch1ComboBox,			panel,	2,	3,	1,	1);
		addComponent(toLabel,				panel,	3,	3,	1,	1);	
		addComponent(ch2ComboBox,			panel,	4,	3,	1,	1);
		addComponent(cancelButton,			panel,	0,	4,	1,	1);
		addComponent(cancelRoomLabel,		panel,	1,	4,	1,	1);
		addComponent(cComboBox,				panel,	2,	4,	1,	1);
		addComponent(c2ComboBox,			panel,	3,	4,	2,	1);
		addComponent(backButton,			panel,	4,	5,	1,	1);
		
		// size and locate the dialog at the center of the screen
		/**this.pack();
		this.setModal(true);
		int w = getWidth();
		int h = getHeight();
		Toolkit tk = Toolkit.getDefaultToolkit();
		Dimension screenSize = tk.getScreenSize();
		int screenWidth = screenSize.width;
		int screenHeight = screenSize.height;
		int x = (screenWidth - w)/2;
		int y = (screenHeight - h)/2;
		setLocation(x,y);
		*/
		this.setSize(600, 300);
		this.add(panel);
		int w = getWidth();
		int h = getHeight();
		Toolkit tk = Toolkit.getDefaultToolkit();
		Dimension screenSize = tk.getScreenSize();
		int screenWidth = screenSize.width;
		int screenHeight = screenSize.height;
		int x = (screenWidth - w)/2;
		int y = (screenHeight - h)/2;
		setLocation(x,y);
	}
	
	// method helping GridBagLayout
	public void addComponent(	JComponent jc, Container c, 
			int x, int y, int w, int h){
		GridBagConstraints gbc = new GridBagConstraints();
		gbc.gridx = x;
		gbc.gridy = y;
		gbc.gridwidth = w;
		gbc.gridheight = h;
		gbc.fill = GridBagConstraints.HORIZONTAL;
		gbc.insets = new Insets(5, 5, 5, 5);
		c.add(jc, gbc);
	}
	
	
	public static void main(String[] args){
		roomManagementDialog temp = new roomManagementDialog( new roomManager());
		temp.setVisible(true);
	}
	
	/**
	public void resetGUI(){
		mergeButton.setEnabled(false);
		Integer[] i1 = rm.findRoomState(1);
		m1ComboBox.removeAllItems();
		for (int i=0; i<i1.length; i++){
			m1ComboBox.addItem(i1[i]);
			System.out.print("Add Item(Merge1): "+i1[i]);
		}
		m2ComboBox.removeAllItems();
		m2ComboBox.setEnabled(false);
		
		changeButton.setEnabled(false);
		ch1ComboBox.removeAllItems();
		for (int i=0; i<i1.length; i++)
			ch1ComboBox.addItem(i1[i]);
		ch2ComboBox.removeAllItems();
		ch2ComboBox.setEnabled(false);
		
		cancelButton.setEnabled(false);
		Integer[] i2 = rm.reservationRooms();
		for (int i=0; i<i2.length; i++)
			cComboBox.addItem(i1[i]);
		c2ComboBox = new JComboBox();
		c2ComboBox.setEnabled(false);
	}
	*/
	
	
	// search the info of the selected room
	class SearchRoomHandler implements ActionListener{

		@Override
		public void actionPerformed(ActionEvent arg0) {
			// TODO Auto-generated method stub
			try{
				roomInfo temp = rm.searchRoom(Integer.parseInt(searchTextField.getText()));
				JOptionPane.showMessageDialog(roomManagementDialog.this, 
						rm.toString(temp), "Room Infomation", JOptionPane.PLAIN_MESSAGE);
			}
			catch(NumberFormatException nfe){
				JOptionPane.showMessageDialog(roomManagementDialog.this, 
						"Wrong Room Number", "Error", JOptionPane.ERROR_MESSAGE);
			}
					
		}
		
	}
	
	// create new room and host
	class CreateRoomHandler implements ActionListener{

		@Override
		public void actionPerformed(ActionEvent arg0) {
			// TODO Auto-generated method stub
			createDialog temp = new createDialog(rm, roomManagementDialog.this);
			temp.setVisible(true);
		}
		
	}
	
	public void afterCreate(int room){
		m1ComboBoxModel.add(""+room);
		ch1ComboBoxModel.add(""+room);
	}
	
	// view room schedule
	class CheckScheduleHandler implements ActionListener{

		@Override
		public void actionPerformed(ActionEvent arg0) {
			// TODO Auto-generated method stub
			checkScheduleFrame temp = new checkScheduleFrame(rm);
			temp.setVisible(true);
			//temp.setAlwaysOnTop(true);
			//
			//roomManagementDialog.this.setVisible(false);
		}
		
	}
	
	// change the state of the selected room from "need to clean" to "in the cleaning"
	class CleanHandler implements ActionListener{

		@Override
		public void actionPerformed(ActionEvent arg0) {
			// TODO Auto-generated method stub
			Vector<String> cleanList = rm.findRoomState(3);
			if (cleanList.size() == 1)
				JOptionPane.showMessageDialog(roomManagementDialog.this, 
						"No room needs to clean");
			else {
				String[] list = new String[cleanList.size()];
				for (int i=0; i<cleanList.size(); i++)
					list[i] = cleanList.get(i);
				Icon icon = null;
				String selected =   (String) JOptionPane.showInputDialog(
						roomManagementDialog.this, "Room to Clean: ", 
						"Clean", JOptionPane.PLAIN_MESSAGE, 
						icon, list, list[0]);
				
				// update info
				if (selected != ""){
					rm.updateRoomState(Integer.parseInt(selected), 2);
					System.out.println("Clean: clean "+selected);
				}
			}
		}
		
	}
	
	// change the state of the selected room from "in the cleaning" to "empty"
	class FinishCleanHandler implements ActionListener{

		@Override
		public void actionPerformed(ActionEvent arg0) {
			// TODO Auto-generated method stub
			Vector<String> cleanList = rm.findRoomState(2);
			if (cleanList.size() == 1)
				JOptionPane.showMessageDialog(roomManagementDialog.this, 
						"No room is in the cleaning");
			else {
				String[] list = new String[cleanList.size()];
				for (int i=0; i<cleanList.size(); i++)
					list[i] = cleanList.get(i);
				Icon icon = null;
				String selected =   (String) JOptionPane.showInputDialog(
						roomManagementDialog.this, "Room to Clean: ", 
						"Clean", JOptionPane.PLAIN_MESSAGE, 
						icon, list, list[0]);
				
				// update info
				if (selected !="") {
					rm.updateRoomState(Integer.parseInt(selected), 0);
					System.out.println("Finish Cleaning: finish Cleaning "+selected);
				}
			}
		}
		
	}
	
	// merge two rooms
	class MergeRoomHandler implements ActionListener{

		@Override
		public void actionPerformed(ActionEvent arg0) {
			// TODO Auto-generated method stub
			Icon icon = null;
			int room1 = Integer.parseInt((String) m1ComboBoxModel.getSelectedItem());
			int room2 = Integer.parseInt((String) m2ComboBoxModel.getSelectedItem());
			
			roomInfo largerRoom = rm.compareType(room1, room2);
			Vector<String> temp = rm.getAvailableRooms(largerRoom.getCurrent().getAmount(), 0);
			
			System.out.println("amount: "+largerRoom.getCurrent().getAmount());
			
			String[] mergeDestination = new String[1+temp.size()];
			for (int i=0; i<mergeDestination.length; i++){
				if (i<temp.size())
					mergeDestination[i] = temp.get(i);
				else mergeDestination[i] = ""+largerRoom.getRoomNum();
			}
			String selected = "";
			try{
				selected =   (String) JOptionPane.showInputDialog(
						roomManagementDialog.this, "Destination: ", 
						"Merge", JOptionPane.PLAIN_MESSAGE, 
						icon, mergeDestination, mergeDestination[0]);
			}
			catch(NumberFormatException nfe){
				JOptionPane.showMessageDialog(roomManagementDialog.this, 
						"Wrong Room Number", "Error", JOptionPane.ERROR_MESSAGE);
			}
			
			
			if (!selected.equals("")){
				rm.mergeRoom(room1, room2, Integer.parseInt(selected));
				System.out.println("Merge Room: merge "+room1+" and "+room2+" to "+selected);
				
				updateGUI();
			}
		}
		
	}
	
	public void updateGUI(){
		mergeButton.setEnabled(false);
		m2ComboBox.setEnabled(false);
		m2ComboBoxModel.init();
		m1ComboBoxModel.setList(rm.findRoomState(1));
		
		changeButton.setEnabled(false);
		ch2ComboBox.setEnabled(false);
		ch2ComboBoxModel.init();
		ch1ComboBoxModel.setList(rm.findRoomState(1));
		
		cancelButton.setEnabled(false);
		c2ComboBox.setEnabled(false);
		c2ComboBoxModel.init();
		cComboBoxModel.setList(rm.reservationRooms());
	}
	
	// get the first room to merge and enable to select the second room
	class Merge1Handler implements ActionListener{

		@Override
		public void actionPerformed(ActionEvent e) {
			// TODO Auto-generated method stub
			m2ComboBoxModel.init();
			if (((JComboBox)e.getSource()).getModel().getSelectedItem().equals("")){
				m2ComboBox.setEnabled(false);
			}
			else {
				m2ComboBox.setEnabled(true);
				Vector<String> rooms = rm.findRoomState(1);
				m2ComboBoxModel.setList(rooms);
				//m2ComboBox.setModel(m2ComboBoxModel);
			}
		}
		
	}
	
	// enable the "Merge Room" button
	class Merge2Handler implements ActionListener{

		@Override
		public void actionPerformed(ActionEvent arg0) {
			// TODO Auto-generated method stub
			if (( (JComboBox) arg0.getSource()).getModel().getSelectedItem().equals(""))
				mergeButton.setEnabled(false);
			else mergeButton.setEnabled(true);
		}
		
	}
	
	// change from one room to another
	class ChangeRoomHandler implements ActionListener{

		@Override
		public void actionPerformed(ActionEvent arg0) {
			// TODO Auto-generated method stub
			int room1 = Integer.parseInt((String) ch1ComboBoxModel.getSelectedItem());
			int room2 = Integer.parseInt((String) ch2ComboBoxModel.getSelectedItem());
			int selected = JOptionPane.showConfirmDialog(roomManagementDialog.this,
					"Are you sure to change Room "+room1+" to Room "+room2+"?", 
			"Change Room", JOptionPane.YES_NO_OPTION);
			if (selected == JOptionPane.YES_OPTION)
				rm.changeRooms(room1, room2);
			
			System.out.println("Change Room: change from "+room1+" to "+room2);
			updateGUI();
		}
		
	}
	
	// get the source room and enable to select the destination room
	class Change1Handler implements ActionListener{

		@Override
		public void actionPerformed(ActionEvent arg0) {
			// TODO Auto-generated method stub
			ch2ComboBoxModel.init();
			if (( (JComboBox) arg0.getSource()).getModel().getSelectedItem().equals("")){
				ch2ComboBox.setEnabled(false);
			}
			else {
				ch2ComboBox.setEnabled(true);
				roomInfo ch1Room = rm.searchRoom(Integer.parseInt((String) ch1ComboBoxModel.getSelectedItem()));
				Vector<String> rooms = rm.getAvailableRooms(rm.typeOfSelectedRoom(ch1Room.getRoomNum()), 0);
				ch2ComboBoxModel.setList(rooms);
			}
		}
		
	}
	
	// enable the "Change Room" button
	class Change2Handler implements ActionListener{

		@Override
		public void actionPerformed(ActionEvent arg0) {
			// TODO Auto-generated method stub
			if (( (JComboBox) arg0.getSource()).getModel().getSelectedItem().equals(""))
				changeButton.setEnabled(false);
			else changeButton.setEnabled(true);
		}
		
	}
	
	
	// cancel the reservation
	class CancelRoomHandler implements ActionListener{

		@Override
		public void actionPerformed(ActionEvent arg0) {
			// TODO Auto-generated method stub
			int cancelRoom = Integer.parseInt((String) cComboBoxModel.getSelectedItem());
			String hostName =  (String) c2ComboBoxModel.getSelectedItem();
			Vector<host> hosts = rm.getReservations(cancelRoom);
			Vector<String> times = new Vector<String>();
			DateFormat format = new SimpleDateFormat("yyyy/MM/dd HH:mm");
			for (int i=0; i<hosts.size(); i++)
				if (hosts.get(i).getName().equals(hostName))
					times.add(format.format(hosts.get(i).getStartTime().getTime()));
			String[] time = new String[times.size()];
			for (int i=0; i<times.size(); i++)
				time[i] = times.get(i);
			if (!hostName.equals("")){
				Icon icon = null;
				String startTime =  (String) JOptionPane.showInputDialog(
						roomManagementDialog.this, "Start Time: ", 
						"Cancel Room", JOptionPane.PLAIN_MESSAGE, 
						icon, time, "");
				rm.deleteReservation(hostName, startTime, cancelRoom);
				updateGUI();
				
				System.out.println("Cancel Room: "+cancelRoom+"\n"
						+"Host: "+hostName+"\n"
						+"Start Time: "+startTime+"\n");
				
			}
		}
		
	}
	
	// enable to select the name of host 
	class Cancel1Handler implements ActionListener{

		@Override
		public void actionPerformed(ActionEvent arg0) {
			// TODO Auto-generated method stub
			c2ComboBoxModel.init();
			if (( (JComboBox) arg0.getSource()).getModel().getSelectedItem().equals(""))
				c2ComboBox.setEnabled(false);
			else {
				c2ComboBox.setEnabled(true);
				Vector<host> hosts = rm.getReservations(Integer.parseInt((String) cComboBoxModel.getSelectedItem()));
				Vector<String> names = new Vector<String>();
				names.add("");
				for (int i=0; i<hosts.size(); i++)
					names.add(hosts.get(i).getName());
				c2ComboBoxModel.setList(names);
			}
		}
		
	}
	
	// enable the "Cancel Room" button
	class Cancel2Handler implements ActionListener{

		@Override
		public void actionPerformed(ActionEvent arg0) {
			// TODO Auto-generated method stub
			if (( (JComboBox) arg0.getSource()).getModel().getSelectedItem().equals(""))
				cancelButton.setEnabled(false);
			else cancelButton.setEnabled(true);
		}
		
	}
	class CancelHandler implements ActionListener{

		@Override
		public void actionPerformed(ActionEvent arg0) {
			// TODO Auto-generated method stub
			roomManagementDialog.this.setVisible(false);
		}
		
	}
}
